package com.zhoug.common3.adapters.recycler2;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.zhoug.common3.utils.LogUtils;
import com.zhoug.common3.utils.RecyclerViewUtils;

import java.util.List;

import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;

/**
 * RecyclerView Adapter接口
 * 支持空数据布局{@link #setEmptyViewEnable(boolean)}
 * 支持错误提示布局{@link #setErrorViewEnable(boolean)}
 * 支持加载更多{@link #setLoadMoreEnable(boolean)}
 *
 * @Author 35574
 * @Date 2021/3/2
 * @Description
 */
public abstract class BaseRecyclerViewAdapter<DT> extends RecyclerView.Adapter<BaseViewHolder> {
    private static final String TAG = ">>>BaseRecyclerViewAdapter";
    private static final boolean DEBUG = false;

    /**
     * ViewType:
     */
    protected static final int VIEW_TYPE_DATA = 1;
    /**
     * ViewType:空数据布局
     */
    protected static final int VIEW_TYPE_EMPTY = -1;
    /**
     * ViewType:错误提示布局
     */
    protected static final int VIEW_TYPE_ERROR = -2;
    /**
     * ViewType:加载更多项布局
     */
    protected static final int VIEW_TYPE_LOAD_MORE = -3;


    private LayoutInflater mLayoutInflater;
    private Context mContext;
    /**
     * 数据集合
     */
    private List<DT> mData;
    /**
     * item单击监听器
     */
    private OnItemClickListener<DT> mOnItemClickListener;
    /**
     * item长按监听器
     */
    private OnItemLongClickListener<DT> mOnItemLongClickListener;
    /**
     * 是否开启加载更多
     */
    private boolean mLoadMoreEnable = false;
    /**
     * 是否开启无数据布局
     */
    private boolean mEmptyViewEnable = true;
    /**
     * 是否开启错误提示布局
     */
    private boolean mErrorViewEnable = true;

    /**
     * 空数据布局
     */
    private EmptyView mEmptyView = new SimpleEmptyView();
    /**
     * 错误提示布局
     */
    private ErrorView mErrorView = new SimpleErrorView();
    /**
     * 加载更多布局
     */
    private LoadMoreView mLoadMoreView = new SimpleLoadMoreView();


    /**
     * 请求状态
     */
    private int mStatus = STATUS_IDLE;

    public static final int STATUS_IDLE = 0;//初始状态
    public static final int STATUS_SUCCESS = 1;//请求成功
    public static final int STATUS_ERROR = 2;//请求失败

    private OnLoadMoreListener mOnLoadMoreListener;
    private RecyclerView mRecyclerView;


    /**
     * item单击回掉接口
     */
    public interface OnItemClickListener<DT> {
        /**
         * @param adapter  BaseRecyclerViewAdapter
         * @param view     触发事件的item
         * @param position item位子
         */
        void onItemClick(BaseRecyclerViewAdapter<DT> adapter, View view, int position);
    }

    /**
     * item长按回掉接口
     */
    public interface OnItemLongClickListener<DT> {
        /**
         * @param adapter  BaseRecyclerViewAdapter
         * @param view     触发事件的item
         * @param position item位子
         * @return
         */
        boolean onItemLongClick(BaseRecyclerViewAdapter<DT> adapter, View view, int position);
    }


    @LayoutRes
    protected abstract int getLayoutId(int viewType);

    protected abstract void onBindData(BaseViewHolder holder, DT data, int position, int viewType);

    protected  void onBindError(BaseViewHolder holder,int position, int viewType){

    }
    protected  void onBindEmpty(BaseViewHolder holder, int position, int viewType){

    }

    public BaseRecyclerViewAdapter() {

    }

    public BaseRecyclerViewAdapter(Context context) {
        this.mContext = context;
    }

    /**
     * 获取数据
     *
     * @return
     */
    public List<DT> getData() {
        return mData;
    }

    /**
     * 设置数据
     *
     * @param data
     */
    public void setData(List<DT> data) {
        this.mData = data;
    }


    /**
     * 获取 mData 的数目
     *
     * @return
     */
    public   int getDataSize() {
        return mData == null ? 0 : mData.size();
    }

    /**
     * 是否无数据
     *
     * @return
     */
    private boolean isEmpty() {
        return getDataSize() == 0;
    }

    protected int getHeaderCount() {
        return 0;
    }

    /**
     * 获取附加的列表
     * @return
     */
    public RecyclerView getAttachedRecyclerView(){
        return mRecyclerView;
    }

    /**
     * 获取指定position位置的数据
     *
     * @param position
     * @return
     */
    public DT getItemData(int position) {
        int dataSize = getDataSize();
        int headerCount = getHeaderCount();
        if (dataSize > 0 && position >= headerCount && position < headerCount + dataSize) {
            return mData.get(position - headerCount);
        }
        return null;
    }



    @Override
    public int getItemCount() {
        if (mStatus == STATUS_SUCCESS) {
            //成功
            //无数据且支持无数据View
            if (mEmptyViewEnable && isEmpty()) {
                return getHeaderCount() + 1;
            }
        } else if (mStatus == STATUS_ERROR) {
            //失败
            //无数据且支持显示错误View
            if (mErrorViewEnable && isEmpty()) {
                return getHeaderCount() + 1;
            }
        }
        //有数据且支持加载更多
        if (mLoadMoreEnable && !isEmpty()) {
            return getHeaderCount() + getDataSize() + 1;
        }

        return getHeaderCount() + getDataSize();
    }


    @Override
    public int getItemViewType(int position) {
        if (mStatus == STATUS_SUCCESS) {
            //成功
            //无数据且支持无数据View
            if (mEmptyViewEnable && isEmpty()) {
                if (position == getHeaderCount()) {
                    return VIEW_TYPE_EMPTY;
                }
            }
        } else if (mStatus == STATUS_ERROR) {
            //失败
            //无数据且支持显示错误View
            if (mErrorViewEnable && isEmpty()) {
                if (position == getHeaderCount()) {
                    return VIEW_TYPE_ERROR;
                }
            }
        }
        //有数据且支持加载更多
        if (mLoadMoreEnable && !isEmpty()) {
            if (position == getItemCount() - 1) {
                return VIEW_TYPE_LOAD_MORE;
            }
        }
        //数据
        int dataSize = getDataSize();
        int headerCount = getHeaderCount();
        if (dataSize > 0 && position >= headerCount && position < headerCount + dataSize) {
            return VIEW_TYPE_DATA;
        }
        return 0;
    }

    @NonNull
    @Override
    public BaseViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        if (mLayoutInflater == null) {
            mLayoutInflater = LayoutInflater.from(parent.getContext());
        }
        if (viewType == VIEW_TYPE_EMPTY) {
          /*  if (DEBUG) {
                LogUtils.d(TAG, "onCreateViewHolder:empty");
            }*/
            return new BaseViewHolder(mEmptyView.getEmptyView(parent), this);
        } else if (viewType == VIEW_TYPE_ERROR) {
//            LogUtils.d(TAG, "onCreateViewHolder:error");
            return new BaseViewHolder(mErrorView.getErrorView(parent), this);
        } else if (viewType == VIEW_TYPE_LOAD_MORE) {
//            LogUtils.d(TAG, "onCreateViewHolder:error");
            return new BaseViewHolder(mLoadMoreView.getLoadMoeView(parent), this);
        }

        return new BaseViewHolder(mLayoutInflater.inflate(getLayoutId(viewType), parent, false), this);

    }

    @Override
    public void onBindViewHolder(@NonNull BaseViewHolder holder, int position) {
        int viewType = getItemViewType(position);
        if (viewType == VIEW_TYPE_LOAD_MORE) {
            mLoadMoreView.refreshView();
        }else if(viewType==VIEW_TYPE_EMPTY){
            onBindEmpty(holder,  position, viewType);
        } else if(viewType==VIEW_TYPE_ERROR){
            onBindError(holder,  position, viewType);
        }else {
            bindOnItemClickListener(holder, position);
            bindItemLongClickListener(holder, position);
            onBindData(holder, getItemData(position), position, viewType);
        }


    }

    /**
     * 绑定单击事件到指定的holder
     *
     * @param holder
     * @param position
     */
    protected void bindOnItemClickListener(BaseViewHolder holder, int position) {
        if (mOnItemClickListener != null) {
            if (!holder.itemView.isClickable()) {
                holder.itemView.setClickable(true);
            }
            holder.itemView.setTag(position);
            holder.itemView.setOnClickListener(v ->{
                if(mOnItemClickListener!=null){
                    mOnItemClickListener.onItemClick(BaseRecyclerViewAdapter.this, v, (Integer) v.getTag());
                }
            });
        }else{
            holder.itemView.setOnClickListener(null);
        }
    }

    /**
     * *绑定长按事件到指定的holder
     *
     * @param holder
     * @param position
     */
    protected void bindItemLongClickListener(BaseViewHolder holder, int position) {
        if (mOnItemLongClickListener != null) {
            if (!holder.itemView.isLongClickable()) {
                holder.itemView.setLongClickable(true);
            }
            holder.itemView.setTag(position);
            holder.itemView.setOnLongClickListener(v -> {
                if(mOnItemLongClickListener!=null){
                    return  mOnItemLongClickListener.onItemLongClick(BaseRecyclerViewAdapter.this, v, (Integer) v.getTag());
                }
                return false;
            });
        }else{
            holder.itemView.setOnLongClickListener(null);
        }
    }

    /**
     * 设置item单击监听
     *
     * @param onItemClickListener
     */
    public void setOnItemClickListener(OnItemClickListener<DT> onItemClickListener) {
        this.mOnItemClickListener = onItemClickListener;
    }

    /**
     * 设置item长按监听
     *
     * @param onItemLongClickListener
     */
    public void setOnItemLongClickListener(OnItemLongClickListener<DT> onItemLongClickListener) {
        this.mOnItemLongClickListener = onItemLongClickListener;
    }

    /**
     * 加载更多监听器
     *
     * @param onLoadMoreListener
     */
    public void setOnLoadMoreListener(OnLoadMoreListener onLoadMoreListener) {
        this.mOnLoadMoreListener = onLoadMoreListener;
    }

    /**
     * 获取 Context
     *
     * @return
     */
    protected final Context getContext() {
        return mContext;
    }

    /**
     * 设置Context
     *
     * @param context
     */
    public final void setContext(Context context) {
        this.mContext = context;
    }

    /**
     * notifyDataSetChanged
     */
    public void notifyDataSetChanged1() {
        notifyDataSetChanged();
    }

    /**
     * 刷新数据加载成功,
     * @see #loadSuccess(List)
     * @deprecated
     * @param data
     */
    @Deprecated
    public void onLoadSuccess(List<DT> data) {
        loadSuccess(data);
    }

    /**
     * 刷新数据加载成功,
     *
     * @param data
     */
    public void loadSuccess(List<DT> data) {
        if (DEBUG) {
            LogUtils.d(TAG, "onLoadSuccess:");
        }
        mStatus = STATUS_SUCCESS;
        mData.clear();
        if (data != null && data.size() > 0) {
            mData.addAll(data);
        }
        if (mLoadMoreEnable) {
            mLoadMoreView.setStatus(LoadMoreView.IDLE);
        }

        notifyDataSetChanged1();
    }


    /**
     * 刷新数据加载失败
     * @see #loadFail(String)
     * @deprecated
     * @param error
     */
    @Deprecated
    public void onLoadFail(String error) {
        loadFail(error);
    }

    /**
     * 设置请求状态
     * @param status {@link #STATUS_IDLE,#STATUS_SUCCESS,#STATUS_ERROR}
     */
    public void setStatus(int status){
        this.mStatus = status;
    }

    /**
     * 刷新数据加载失败
     *
     * @param error
     */
    public void loadFail(String error) {
        if (DEBUG) {
            LogUtils.d(TAG, "onLoadFail:error=" + error);
        }
        mStatus = STATUS_ERROR;
        if (mErrorViewEnable) {
            mErrorView.setErrorText(error);
        }
        mData.clear();
        if (mLoadMoreEnable) {
            mLoadMoreView.setStatus(LoadMoreView.IDLE);
        }
        notifyDataSetChanged1();
    }


    /**
     * 加载更多成功
     * @see #loadMoreSuccess(List)
     * @deprecated
     * @param data
     */
    @Deprecated
    public void onLoadMoreSuccess(List<DT> data) {
        loadMoreSuccess(data);

    }

    /**
     * 加载更多成功
     *
     * @param data
     */
    public void loadMoreSuccess(List<DT> data) {
        if (DEBUG) {
            LogUtils.d(TAG, "onLoadMoreSuccess:");
        }
        if (data != null && data.size() > 0) {
            mData.addAll(data);
            mLoadMoreView.setStatus(LoadMoreView.SUCCESS);
        } else {
            mLoadMoreView.setStatus(LoadMoreView.END);
        }
        notifyDataSetChanged1();


    }

    /**
     * 加载更多失败
     * @see #loadMoreFail()
     * @deprecated
     */
    @Deprecated
    public void onLoadMoreFail() {
        loadMoreFail();
    }
    /**
     * 加载更多失败
     */
    public void loadMoreFail() {
        if (DEBUG) {
            LogUtils.d(TAG, "onLoadMoreFail:");
        }
        mLoadMoreView.setStatus(LoadMoreView.FAIL);
        notifyDataSetChanged1();
    }


    public void setLoadMoreStatus(@LoadMoreView.Status int loadMoreStatus) {
        mLoadMoreView.setStatus(loadMoreStatus);

    }


    public boolean isLoadMoreEnable() {
        return mLoadMoreEnable;
    }

    /**
     * 启用加载更多
     *
     * @param enable
     */
    public void setLoadMoreEnable(boolean enable) {
        this.mLoadMoreEnable = enable;
        initLoadMore();
    }

    public void setLoadMoreView(LoadMoreView loadMoreView) {
        this.mLoadMoreView = loadMoreView;
    }

    public boolean isEmptyViewEnable() {
        return mEmptyViewEnable;
    }

    boolean hideNoMoreTextWhenUnScroll;

    /**
     * 数据不满屏时(不能滚动)当状态为END时隐藏"没有更多"提示
     *
     * @param hide
     */
    public void setHideNoMoreTextWhenUnScroll(boolean hide) {
        this.hideNoMoreTextWhenUnScroll = hide;
    }

    /**
     * 启用空布局
     *
     * @param enable
     */
    public void setEmptyViewEnable(boolean enable) {
        this.mEmptyViewEnable = enable;
    }

    public void setEmptyView(EmptyView emptyView) {
        this.mEmptyView = emptyView;
    }

    /**
     * 设置空布局的提示文字
     *
     * @param emptyText
     */
    public void setEmptyText(CharSequence emptyText) {
        if (mEmptyView != null) {
            mEmptyView.setEmptyText(emptyText);
        }
    }


    public boolean isErrorViewEnable() {
        return mErrorViewEnable;
    }

    /**
     * 启用错误提示View
     *
     * @param enable
     */
    public void setErrorViewEnable(boolean enable) {
        this.mErrorViewEnable = enable;
    }

    public void setErrorView(ErrorView errorView) {
        this.mErrorView = errorView;
    }

    /**
     * 是否需要独占一行
     *
     * @param position
     * @return
     */
    private boolean isFullSpan(int position) {
        //emptyView,ErrorView,LoadMoreView独占一行
        int itemViewType = getItemViewType(position);
        ;
        return itemViewType == VIEW_TYPE_EMPTY || itemViewType == VIEW_TYPE_ERROR || itemViewType == VIEW_TYPE_LOAD_MORE;
    }


    /**
     * 每个item显示到屏幕上调用
     *
     * @param holder
     */
    @Override
    public void onViewAttachedToWindow(@NonNull BaseViewHolder holder) {
        super.onViewAttachedToWindow(holder);
        //emptyView,ErrorView,LoadMoreView独占一行
        int position = holder.getLayoutPosition();
        if (isFullSpan(position)) {
            ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();
            if (lp instanceof StaggeredGridLayoutManager.LayoutParams) {
                StaggeredGridLayoutManager.LayoutParams p =
                        (StaggeredGridLayoutManager.LayoutParams) lp;
                p.setFullSpan(true);
            }
        }
    }

    /**
     * adapter绑定RecyclerView时调用
     *
     * @param recyclerView
     */
    @Override
    public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
        this.mRecyclerView = recyclerView;
        //emptyView,ErrorView,LoadMoreView独占一行
        RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
        if (layoutManager instanceof GridLayoutManager) {
            final GridLayoutManager gridLayoutManager = (GridLayoutManager) layoutManager;
            gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                @Override
                public int getSpanSize(int position) {
                    if (isFullSpan(position)) {
                        return gridLayoutManager.getSpanCount();
                    }
                    return 1;
                }
            });
        }

        initLoadMore();
    }

    /**
     * 初始化loadMore
     */
    private void initLoadMore() {
        //加载更多监听设置
        if (mRecyclerView != null) {
            mRecyclerView.removeOnScrollListener(mOnScrollListener);
            mRecyclerView.removeOnLayoutChangeListener(mOnLayoutChangeListener);
            if (mLoadMoreEnable) {
                if (DEBUG) {
                    LogUtils.d(TAG, "onAttachedToRecyclerView:加载更多监听设置");
                }
                mRecyclerView.addOnScrollListener(mOnScrollListener);
                mRecyclerView.addOnLayoutChangeListener(mOnLayoutChangeListener);
            }

        }
    }

    /**
     * 监听滚动到底部后自动加载更多
     */
    private RecyclerView.OnScrollListener mOnScrollListener = new RecyclerView.OnScrollListener() {
        private boolean isSlidingUpward = false;


        @Override
        public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
            super.onScrollStateChanged(recyclerView, newState);
            if (!isSlidingUpward || newState != RecyclerView.SCROLL_STATE_IDLE || skipLoadMore())
                return;

            RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
            if (layoutManager != null) {
                int childCount = layoutManager.getChildCount();
                if (childCount >= 1) {
                    View lastChildView = layoutManager.getChildAt(childCount - 1);
                    if (lastChildView != null) {
                        int lastPosition = layoutManager.getPosition(lastChildView);
                        if (lastPosition == getItemCount() - 1) {
                            if (DEBUG) {
                                LogUtils.d(TAG, "onScrollStateChanged:最后一个item显示");
                            }
                            startLoadMore();
                        }

                    }
                }

            }

        }

        @Override
        public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            if (skipLoadMore()) {
                return;
            }
            // 大于0表示正在向上滑动，小于等于0表示停止或向下滑动
            isSlidingUpward = dy > 0;
           /* if (DEBUG) {
                LogUtils.d(TAG, "onScrolled:dy=" + dy);
            }*/
            //解决第一次加载数据后数据不满屏(即不能滚动的情况)
            //自动加载更多
            if (dy == 0 && !isEmpty() && !RecyclerViewUtils.canScroll(recyclerView)) {
                if (DEBUG) {
                    LogUtils.d(TAG, "onScrolled:不能滚动");
                }
                startLoadMore();
            }
        }


    };
    /**
     * 不满屏时解决刷新后由于数据没变化不回掉RecyclerView.OnScrollListener,不能触发加载更多的问题
     */
    private View.OnLayoutChangeListener mOnLayoutChangeListener = new View.OnLayoutChangeListener() {
        @Override
        public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
            if (hideNoMoreTextWhenUnScroll && mLoadMoreView.getStatus() == LoadMoreView.END && !RecyclerViewUtils.canScroll((RecyclerView) v)) {
                if (DEBUG) {
                    LogUtils.d(TAG, "onLayoutChange:不能滚动,没有更多数据了,隐藏提示");
                }
                mLoadMoreView.setStatus(LoadMoreView.END_GONE);
                return;
            }
            if (skipLoadMore() || mLoadMoreView.getStatus() == LoadMoreView.FAIL) {
                return;
            }
            //解决第一次加载数据后数据不满屏(即不能滚动的情况)
            //自动加载更多
            if (!isEmpty() && !RecyclerViewUtils.canScroll((RecyclerView) v)) {
                if (DEBUG) {
                    LogUtils.d(TAG, "onLayoutChange:不能滚动");
                }
                startLoadMore();
            }
        }
    };


    /**
     * 忽律判断是否需要加载更多
     *
     * @return
     */
    private boolean skipLoadMore() {
        //不支持加载更多,没有设置监听器
        //没有更多了,正在加载
        if (!mLoadMoreEnable || mOnLoadMoreListener == null ||
                mLoadMoreView.getStatus() == LoadMoreView.END ||
                mLoadMoreView.getStatus() == LoadMoreView.LOADING) {
            return true;
        }
        return false;
    }

    /**
     * 开始加载更多
     */
    private void startLoadMore() {
        if (!skipLoadMore()) {
            if (DEBUG) {
                LogUtils.d(TAG, "startLoadMore:开始加载更多");
            }
            mLoadMoreView.setStatus(LoadMoreView.LOADING);
            mOnLoadMoreListener.onStartLoadMore();
        }


    }

}
